﻿/*
* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
*
* This software is provided 'as-is', without any express or implied
* warranty.  In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/


package Box2D.test.TestBed{
	
	
	
	import Box2D.Collision.*;
	import Box2D.Collision.Shapes.*;
	import Box2D.Common.*;
	import Box2D.Common.Math.*;
	import Box2D.Dynamics.*;
	import Box2D.Dynamics.Contacts.*;
	import Box2D.Dynamics.Joints.*;
	import Box2D.test.Main;
	
	import assets.avatar.BodyAsset;
	import assets.avatar.HeadAsset;
	import assets.avatar.LeftFootAsset;
	import assets.avatar.LeftHandAsset;
	import assets.avatar.RightFootAsset;
	import assets.avatar.RightHandAsset;
	
	import com.waitingsnow.core.display.player.BmpDataPlayer;
	import com.waitingsnow.core.util.core.MathUtil;
	import com.waitingsnow.core.util.display.BmpDataUtil;
	
	import flash.display.Sprite;
	
	
	
	public class TestRagdoll_avatar extends Test{
		
		public function TestRagdoll_avatar(){
			
			// Set Text field
			Main.m_aboutText.text = "Ragdolls";
			
			var circ:b2CircleShape; 
			var box:b2PolygonShape;
			var bd:b2BodyDef/* = new b2BodyDef()*/;
			var jd:b2RevoluteJointDef = new b2RevoluteJointDef();
			var fixtureDef:b2FixtureDef = new b2FixtureDef();
			
			// Add 5 ragdolls along the top
			for (var i:int = 0; i < 2; i++){
				var startX:Number = 70 + Math.random() * 20 + 480 * i;
				var startY:Number = 20 + Math.random() * 50;
				
				// BODIES
				// Set these to dynamic bodies
//				bd.type = b2Body.b2_dynamicBody;
				
				// Head
				bd = createBD();
				circ = new b2CircleShape( 25 / m_physScale );
				fixtureDef.shape = circ;
				fixtureDef.density = 1.0;
				fixtureDef.friction = 0.1;
				fixtureDef.restitution = 0.1;
				bd.userData = createBmpPlay(HeadAsset);;
				bd.position.Set(startX / m_physScale, startY / m_physScale);
				var head:b2Body = m_world.CreateBody(bd);
				head.CreateFixture(fixtureDef);
				//if (i == 0){
				head.ApplyLinearImpulse(new b2Vec2(Math.random() * 100 - 50, Math.random() * 100 - 50), head.GetWorldCenter());
				//}
				// Torso1
				bd = createBD();
				box = new b2PolygonShape();
				box.SetAsBox(25 / m_physScale, 25 / m_physScale);
				fixtureDef.shape = box;
				fixtureDef.density = 1.0;
				fixtureDef.friction = 0.1;
				fixtureDef.restitution = 1;
				bd.userData = createBmpPlay(BodyAsset, 50, 50);
				bd.position.Set(startX / m_physScale, (startY + 38) / m_physScale);
				var torso1:b2Body = m_world.CreateBody(bd);
				torso1.CreateFixture(fixtureDef);
				
				// Torso2
				fixtureDef.density = 1.0;
				fixtureDef.friction = 0.1;
				fixtureDef.restitution = 0.1;
				bd = createBD();
				box = new b2PolygonShape();
				box.SetAsBox(15 / m_physScale, 7.5 / m_physScale);
				fixtureDef.shape = box;
				bd.userData = createBmpPlay(LeftHandAsset, 25, 15);
				bd.position.Set((startX-25) / m_physScale, (startY + 30) / m_physScale);
				/*bd.angle = 20;*/
				var torso2:b2Body = m_world.CreateBody(bd);
				torso2.CreateFixture(fixtureDef);
				// Torso3
				bd = createBD();
				box.SetAsBox(12.5 / m_physScale, 7.5 / m_physScale);
				fixtureDef.shape = box;
				bd.userData = createBmpPlay(RightHandAsset, 25, 15);
				bd.position.Set((startX + 25) / m_physScale, (startY + 30) / m_physScale);
				/*bd.angle = -20;*/
				var torso3:b2Body = m_world.CreateBody(bd);
				torso3.CreateFixture(fixtureDef);
				
				// UpperArm
				fixtureDef.density = 12.0;
				fixtureDef.friction = 0.1;
				fixtureDef.restitution = 0.1;
				// L
				box = new b2PolygonShape();
				box.SetAsBox(10 / m_physScale, 10 / m_physScale);
				fixtureDef.shape = box;
				bd.userData = createBmpPlay(LeftFootAsset, 10, 20);
				bd.position.Set((startX - 15) / m_physScale, (startY + 60) / m_physScale);
				var leftFoot:b2Body = m_world.CreateBody(bd);
				leftFoot.CreateFixture(fixtureDef);
				// R
				box = new b2PolygonShape();
				box.SetAsBox(10 / m_physScale, 10 / m_physScale);
				fixtureDef.shape = box;
				bd.userData = createBmpPlay(RightFootAsset, 10, 20);
				bd.position.Set((startX + 15) / m_physScale, (startY + 60) / m_physScale);
				var rightFoot:b2Body = m_world.CreateBody(bd);
				rightFoot.CreateFixture(fixtureDef);
//				
//				// LowerArm
//				fixtureDef.density = 1.0;
//				fixtureDef.friction = 0.4;
//				fixtureDef.restitution = 0.1;
//				// L
//				box = new b2PolygonShape();
//				box.SetAsBox(17 / m_physScale, 6 / m_physScale);
//				fixtureDef.shape = box;
//				bd.position.Set((startX - 57) / m_physScale, (startY + 20) / m_physScale);
//				var lowerArmL:b2Body = m_world.CreateBody(bd);
//				lowerArmL.CreateFixture(fixtureDef);
//				// R
//				box = new b2PolygonShape();
//				box.SetAsBox(17 / m_physScale, 6 / m_physScale);
//				fixtureDef.shape = box;
//				bd.position.Set((startX + 57) / m_physScale, (startY + 20) / m_physScale);
//				var lowerArmR:b2Body = m_world.CreateBody(bd);
//				lowerArmR.CreateFixture(fixtureDef);
//				
//				// UpperLeg
//				fixtureDef.density = 1.0;
//				fixtureDef.friction = 0.4;
//				fixtureDef.restitution = 0.1;
//				// L
//				box = new b2PolygonShape();
//				box.SetAsBox(7.5 / m_physScale, 22 / m_physScale);
//				fixtureDef.shape = box;
//				bd.position.Set((startX - 8) / m_physScale, (startY + 85) / m_physScale);
//				var upperLegL:b2Body = m_world.CreateBody(bd);
//				upperLegL.CreateFixture(fixtureDef);
//				// R
//				box = new b2PolygonShape();
//				box.SetAsBox(7.5 / m_physScale, 22 / m_physScale);
//				fixtureDef.shape = box;
//				bd.position.Set((startX + 8) / m_physScale, (startY + 85) / m_physScale);
//				var upperLegR:b2Body = m_world.CreateBody(bd);
//				upperLegR.CreateFixture(fixtureDef);
//				
//				// LowerLeg
//				fixtureDef.density = 1.0;
//				fixtureDef.friction = 0.4;
//				fixtureDef.restitution = 0.1;
//				// L
//				box = new b2PolygonShape();
//				box.SetAsBox(6 / m_physScale, 20 / m_physScale);
//				fixtureDef.shape = box;
//				bd.position.Set((startX - 8) / m_physScale, (startY + 120) / m_physScale);
//				var lowerLegL:b2Body = m_world.CreateBody(bd);
//				lowerLegL.CreateFixture(fixtureDef);
//				// R
//				box = new b2PolygonShape();
//				box.SetAsBox(6 / m_physScale, 20 / m_physScale);
//				fixtureDef.shape = box;
//				bd.position.Set((startX + 8) / m_physScale, (startY + 120) / m_physScale);
//				var lowerLegR:b2Body = m_world.CreateBody(bd);
//				lowerLegR.CreateFixture(fixtureDef);
//				
//				
				// JOINTS
				jd.enableLimit = true;
				jd.enableMotor = true;
				
				// Head to shoulders
				jd.lowerAngle = MathUtil.getRadius(-30);
				jd.upperAngle = MathUtil.getRadius(30);
				jd.Initialize(head, torso1, new b2Vec2(startX / m_physScale, (startY + 25) / m_physScale));
				m_world.CreateJoint(jd);
				
//				//move
//				var ground:b2Body = m_world.GetGroundBody();
//				var pjd:b2PrismaticJointDef = new b2PrismaticJointDef();
//				pjd.Initialize(ground, torso1, new b2Vec2(100.0/m_physScale, (360.0-255.0)/m_physScale), new b2Vec2(0.0, 1.0));
//				pjd.maxMotorForce = 500.0;
//				pjd.enableMotor = true;
//				m_world.CreateJoint(pjd) as b2PrismaticJoint;
				
				// Upper arm to shoulders
				// L
				jd.lowerAngle = MathUtil.getRadius(0);
				jd.upperAngle =  MathUtil.getRadius(0);
				jd.Initialize(torso2, torso1, new b2Vec2((startX - 25) / m_physScale, (startY + 40) / m_physScale));
				m_world.CreateJoint(jd);
				// R
				jd.lowerAngle = MathUtil.getRadius(0);
				jd.upperAngle = MathUtil.getRadius(0);
				jd.Initialize(torso3, torso1, new b2Vec2((startX + 25) / m_physScale, (startY + 40) / m_physScale));
				m_world.CreateJoint(jd);
				
				// Lower arm to upper arm
				// L
				jd.lowerAngle = MathUtil.getRadius(0);
				jd.upperAngle = MathUtil.getRadius(0);
				jd.Initialize(leftFoot, torso1, new b2Vec2((startX - 10) / m_physScale, (startY + 60) / m_physScale));
				m_world.CreateJoint(jd);
				// R
				jd.lowerAngle = MathUtil.getRadius(0);
				jd.upperAngle = MathUtil.getRadius(0);
				jd.Initialize(rightFoot, torso1, new b2Vec2((startX + 10) / m_physScale, (startY + 60) / m_physScale));
				m_world.CreateJoint(jd);
//				
				// Shoulders/stomach
//				jd.lowerAngle = -15 / (180/Math.PI);
//				jd.upperAngle = 15 / (180/Math.PI);
//				jd.Initialize(torso1, torso2, new b2Vec2(startX / m_physScale, (startY + 35) / m_physScale));
//				m_world.CreateJoint(jd);
//				// Stomach/hips
//				jd.Initialize(torso2, torso3, new b2Vec2(startX / m_physScale, (startY + 50) / m_physScale));
//				m_world.CreateJoint(jd);
//				
//				// Torso to upper leg
//				// L
//				jd.lowerAngle = -25 / (180/Math.PI);
//				jd.upperAngle = 45 / (180/Math.PI);
//				jd.Initialize(torso3, upperLegL, new b2Vec2((startX - 8) / m_physScale, (startY + 72) / m_physScale));
//				m_world.CreateJoint(jd);
//				// R
//				jd.lowerAngle = -45 / (180/Math.PI);
//				jd.upperAngle = 25 / (180/Math.PI);
//				jd.Initialize(torso3, upperLegR, new b2Vec2((startX + 8) / m_physScale, (startY + 72) / m_physScale));
//				m_world.CreateJoint(jd);
//				
//				// Upper leg to lower leg
//				// L
//				jd.lowerAngle = -25 / (180/Math.PI);
//				jd.upperAngle = 115 / (180/Math.PI);
//				jd.Initialize(upperLegL, lowerLegL, new b2Vec2((startX - 8) / m_physScale, (startY + 105) / m_physScale));
//				m_world.CreateJoint(jd);
//				// R
//				jd.lowerAngle = -115 / (180/Math.PI);
//				jd.upperAngle = 25 / (180/Math.PI);
//				jd.Initialize(upperLegR, lowerLegR, new b2Vec2((startX + 8) / m_physScale, (startY + 105) / m_physScale));
//				m_world.CreateJoint(jd);
				
			}
			
			
			// Add stairs on the left, these are static bodies so set the type accordingly
//			bd = createBD();
//			bd.type = b2Body.b2_staticBody;
//			fixtureDef.density = 0.0;
//			fixtureDef.friction = 0.4;
//			fixtureDef.restitution = 0.3;
//			for (var j:int = 1; j <= 10; j++) {
//				box = new b2PolygonShape();
//				box.SetAsBox((10*j) / m_physScale, 10 / m_physScale);
//				fixtureDef.shape = box;
//				bd.position.Set((10*j) / m_physScale, (150 + 20*j) / m_physScale);
//				head = m_world.CreateBody(bd);
//				head.CreateFixture(fixtureDef);
//			}
//			
//			// Add stairs on the right
//			for (var k:int = 1; k <= 10; k++){
//				box = new b2PolygonShape();
//				box.SetAsBox((10 * k) / m_physScale, 10 / m_physScale);
//				fixtureDef.shape = box;
//				bd.position.Set((640-10*k) / m_physScale, (150 + 20*k) / m_physScale);
//				head = m_world.CreateBody(bd);
//				head.CreateFixture(fixtureDef);
//			}
//			
//			box = new b2PolygonShape();
//			box.SetAsBox(50 / m_physScale, 60 / m_physScale);
//			fixtureDef.shape = box;
//			bd.position.Set(100 / m_physScale, 200 / m_physScale);
//			head = m_world.CreateBody(bd);
//			head.CreateFixture(fixtureDef);
//			Logger.debug("x: ", 320 / m_physScale, 280 / m_physScale);
			
			
		}
		
		private function createBmpPlay(type:Class, width:int = 50, height:int = 50):Sprite
		{
			var cls:* = new type();
			var avatarBmp:BmpDataPlayer = new BmpDataPlayer();
			avatarBmp.repeatCount = 0;
			avatarBmp.bmpDataArr = BmpDataUtil.getBmpDataArr(cls, width, height);
			avatarBmp.play();
			var sp:Sprite = new Sprite();
			avatarBmp.x = -avatarBmp.width*0.5;
			avatarBmp.y = -avatarBmp.height*0.5;
			sp.addChild(avatarBmp);
			sp.width = width;
			sp.height = height;
			m_sprite.stage.addChildAt(sp, 0);
			return sp;
		}
		
		private function createBD():b2BodyDef
		{
			var bd:b2BodyDef = new b2BodyDef();
			bd.type = b2Body.b2_dynamicBody;
			/*bd.fixedRotation = true;*/
			bd.bullet = true;
			return bd;
		}
		
		private function getAngel(radius:Number):Number
		{
			return radius*180/Math.PI;
		}
		
		private function getRadius(angel:Number):Number
		{
			return angel*Math.PI/180;
		}
		
		
		//======================
		// Member Data 
		//======================
	}
	
}